package com.demo.spring.autowird;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.context.support.GenericApplicationContext;

public class Autowired底层演示6_Array和List {
	
	public static void main(String[] args) throws Exception {
		GenericApplicationContext context = new GenericApplicationContext();
		context.registerBeanDefinition("service", new AnnotatedGenericBeanDefinition(Service.class));
		context.registerBeanDefinition("target", new AnnotatedGenericBeanDefinition(Target.class));
		DependencyDescriptor dd1 = new DependencyDescriptor(Target.class.getDeclaredField("serviceArray"), true);
		// 如果是数组类型
		if(dd1.getDependencyType().isArray()) {
			// 得到数组元素的类型
			Class<?> componentType = dd1.getDependencyType().getComponentType();
			System.out.println(componentType);
			// 获取数组元素的类型对应的bean name
			String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context.getDefaultListableBeanFactory(), componentType);
			List<Object> beans = new ArrayList<>();
			for(String name : names) {
				System.out.println("===:" + name);
				Object bean = context.getDefaultListableBeanFactory().getBean(name);
				beans.add(bean);
			}
			// 把集合转为数组，这个数组就可以赋值给serviceArray
			Object array = context.getDefaultListableBeanFactory().getTypeConverter().convertIfNecessary(beans, dd1.getDependencyType());
			System.out.println(array);
		}
		
		dd1 = new DependencyDescriptor(Target.class.getDeclaredField("serviceList"), true);
		// 如果是List类型
		if(dd1.getDependencyType() == List.class) {
			// 获取泛型
			Class<?> componentType = dd1.getResolvableType().getGeneric(0).resolve();
			System.out.println(componentType);
			// 获取数组元素的类型对应的bean name
			String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context.getDefaultListableBeanFactory(), componentType);
			List<Object> beans = new ArrayList<>();
			for(String name : names) {
				System.out.println("===:" + name);
				Object bean = context.getDefaultListableBeanFactory().getBean(name);
				beans.add(bean);
			}
			System.out.println(beans);
		}
	}
	
	static class Target {
		@Autowired
		private Service[] serviceArray;
		@Autowired
		private List<Service> serviceList;
	}
	
	static class Service {
		
	}

}
